﻿using System;
using System.Threading.Tasks;
using System.Collections.Generic;
using Microsoft.Extensions.Logging;
using LPP.Entity.Orders;
using LPP.Entity.Enums;
using LPP.Entity.Exceptions;

using LPP.Service.OrderServices;

namespace LPP.Service.Payment;

/// <summary>
/// 支付服务实现
/// </summary>
public class PaymentService : IPaymentService
{
    private readonly IAlipayService _alipayService;
    private readonly IWeChatPayService _wechatPayService;
    private readonly IOrderService _orderService;
    private readonly ILogger<PaymentService> _logger;

    public PaymentService(
        IAlipayService alipayService,
        IWeChatPayService wechatPayService,
        IOrderService orderService,
        ILogger<PaymentService> logger)
    {
        _alipayService = alipayService ?? throw new ArgumentNullException(nameof(alipayService));
        _wechatPayService = wechatPayService ?? throw new ArgumentNullException(nameof(wechatPayService));
        _orderService = orderService ?? throw new ArgumentNullException(nameof(orderService));
        _logger = logger ?? throw new ArgumentNullException(nameof(logger));
    }

    public async Task<string> CreatePaymentAsync(Order order)
    {
        try
        {
            if (order == null)
            {
                throw new ArgumentNullException(nameof(order));
            }

            return order.PaymentMethod switch
            {
                PaymentMethod.Alipay => await CreateAliPayPaymentAsync(order.OrderID, order.Amount),
                PaymentMethod.WeChatPay => await CreateWeChatPayPaymentAsync(order.OrderID, order.Amount),
                _ => throw new PaymentException($"不支持的支付方式: {order.PaymentMethod}")
            };
        }
        catch (Exception ex) when (ex is not PaymentException)
        {
            _logger.LogError(ex, "创建支付失败: OrderId={OrderId}, PaymentMethod={PaymentMethod}",
                order?.OrderID, order?.PaymentMethod);
            throw new PaymentException("创建支付失败", ex);
        }
    }

    public async Task<string> CreateAliPayPaymentAsync(string orderId, decimal amount)
    {
        try
        {
            var order = await GetAndValidateOrder(orderId, amount);
            return await _alipayService.CreatePaymentAsync(order);
        }
        catch (Exception ex) when (ex is not PaymentException)
        {
            _logger.LogError(ex, "创建支付宝支付失败: OrderId={OrderId}, Amount={Amount}",
                orderId, amount);
            throw new PaymentException("创建支付宝支付失败", ex);
        }
    }

    public async Task<string> CreateWeChatPayPaymentAsync(string orderId, decimal amount)
    {
        try
        {
            var order = await GetAndValidateOrder(orderId, amount);
            return await _wechatPayService.CreatePaymentAsync(order);
        }
        catch (Exception ex) when (ex is not PaymentException)
        {
            _logger.LogError(ex, "创建微信支付失败: OrderId={OrderId}, Amount={Amount}",
                orderId, amount);
            throw new PaymentException("创建微信支付失败", ex);
        }
    }

    public bool VerifyNotify(Dictionary<string, string> parameters)
    {
        try
        {
            if (parameters == null)
            {
                throw new ArgumentNullException(nameof(parameters));
            }

            // 根据参数判断支付方式
            return parameters.ContainsKey("trade_type")
                ? _wechatPayService.VerifyNotify(parameters)
                : _alipayService.VerifyNotify(parameters);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "验证支付通知失败: {@Parameters}", parameters);
            return false;
        }
    }

    public async Task<bool> VerifyPaymentAsync(string orderId, string tradeNo)
    {
        try
        {
            var order = await _orderService.GetOrderByIdAsync(orderId);
            if (order == null)
            {
                _logger.LogWarning("订单不存在: OrderId={OrderId}", orderId);
                return false;
            }

            return order.PaymentMethod switch
            {
                PaymentMethod.Alipay => await _alipayService.VerifyPaymentAsync(orderId, tradeNo),
                PaymentMethod.WeChatPay => await _wechatPayService.VerifyPaymentAsync(orderId, tradeNo),
                _ => false
            };
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "验证支付状态失败: OrderId={OrderId}, TradeNo={TradeNo}",
                orderId, tradeNo);
            return false;
        }
    }

    public async Task<bool> VerifyPaymentAsync(string orderId, string tradeNo, string paymentType)
    {
        try
        {
            if (string.IsNullOrEmpty(paymentType))
            {
                throw new ArgumentException("支付方式不能为空", nameof(paymentType));
            }

            return paymentType.ToLower() switch
            {
                "alipay" => await _alipayService.VerifyPaymentAsync(orderId, tradeNo),
                "wechat" => await _wechatPayService.VerifyPaymentAsync(orderId, tradeNo),
                _ => throw new PaymentException($"不支持的支付方式: {paymentType}")
            };
        }
        catch (Exception ex) when (ex is not PaymentException)
        {
            _logger.LogError(ex,
                "验证支付状态失败: OrderId={OrderId}, TradeNo={TradeNo}, PaymentType={PaymentType}",
                orderId, tradeNo, paymentType);
            throw new PaymentException("验证支付状态失败", ex);
        }
    }

    public async Task<bool> HandlePaymentNotifyAsync(Dictionary<string, string> parameters)
    {
        try
        {
            if (parameters == null)
            {
                throw new ArgumentNullException(nameof(parameters));
            }

            return parameters.ContainsKey("trade_type")
                ? await HandleWeChatPayNotifyAsync(parameters)
                : await HandleAliPayNotifyAsync(parameters);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "处理支付通知失败: {@Parameters}", parameters);
            return false;
        }
    }

    public async Task<bool> HandleAliPayNotifyAsync(Dictionary<string, string> parameters)
    {
        try
        {
            if (!_alipayService.VerifyNotify(parameters))
            {
                _logger.LogWarning("支付宝通知签名验证失败");
                return false;
            }

            return await _alipayService.HandlePaymentNotifyAsync(parameters);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "处理支付宝通知失败: {@Parameters}", parameters);
            return false;
        }
    }

    public async Task<bool> HandleWeChatPayNotifyAsync(Dictionary<string, string> parameters)
    {
        try
        {
            if (!_wechatPayService.VerifyNotify(parameters))
            {
                _logger.LogWarning("微信支付通知签名验证失败");
                return false;
            }

            return await _wechatPayService.HandlePaymentNotifyAsync(parameters);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "处理微信支付通知失败: {@Parameters}", parameters);
            return false;
        }
    }

    private async Task<Order> GetAndValidateOrder(string orderId, decimal amount)
    {
        if (string.IsNullOrEmpty(orderId))
        {
            throw new ArgumentException("订单ID不能为空", nameof(orderId));
        }

        if (amount <= 0)
        {
            throw new ArgumentException("订单金额必须大于0", nameof(amount));
        }

        var order = await _orderService.GetOrderByIdAsync(orderId);
        if (order == null)
        {
            throw new PaymentException("订单不存在");
        }

        if (order.Amount != amount)
        {
            throw new PaymentException("订单金额不匹配");
        }

        if (order.Status != OrderStatus.Pending)
        {
            throw new PaymentException($"订单状态不正确: {order.Status}");
        }

        return order;
    }
}